package com.example.archivemanagement.controller;

import com.example.archivemanagement.audit.AuditEvent;
import com.example.archivemanagement.audit.AuditEventProducer;
import com.example.archivemanagement.entity.User;
import com.example.archivemanagement.security.JwtTokenProvider;
import com.example.archivemanagement.service.StatisticsService;
import com.example.archivemanagement.service.UserService;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/auth")
@CrossOrigin(origins = "*", maxAge = 3600)
public class AuthController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtTokenProvider tokenProvider;

    @Autowired
    private AuditEventProducer auditEventProducer;

    @Autowired
    private StatisticsService statisticsService;

    @Autowired
    private UserService userService;

    @PostMapping("/login")
    public ResponseEntity<?> login(@Valid @RequestBody LoginRequest loginRequest) {
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                        loginRequest.getUsername(), loginRequest.getPassword()
                )
        );

        SecurityContextHolder.getContext().setAuthentication(authentication);
        String jwt = tokenProvider.generateToken(authentication);

        User user = userService.findByUsername(loginRequest.getUsername());
        user.setToken(jwt);

        AuditEvent event = new AuditEvent("login",
                UUID.randomUUID().toString(), "登陆",
                user.getUsername(), LocalDateTime.now(), "");

        auditEventProducer.sendAuditEvent(event);
        statisticsService.addTodayVisits();

        return ResponseEntity.ok(user);
    }

    @PostMapping("/logout")
    public ResponseEntity<?> logout(HttpServletRequest request) {
        // 从请求头中获取JWT令牌
        String token = tokenProvider.resolveToken(request);

        if (token != null && tokenProvider.validateToken(token)) {
            // 获取当前认证信息
            Authentication authentication = tokenProvider.getAuthentication(token);

            // 清除SecurityContext中的认证信息
            SecurityContextHolder.clearContext();

            // 失效JWT令牌（将其添加到黑名单或设置失效时间）
            tokenProvider.invalidateToken(token);

            return ResponseEntity.ok("User logged out successfully!");
        }

        return ResponseEntity.badRequest().body("Invalid token or already logged out!");
    }


    @PostMapping("/register")
    public ResponseEntity<?> register(@Valid @RequestBody RegisterRequest registerRequest) {
        if (userService.existsByUsername(registerRequest.getUsername())) {
            return ResponseEntity.badRequest().body("Username is already taken!");
        }

        User user = new User();
        user.setUsername(registerRequest.getUsername());
        user.setPassword(registerRequest.getPassword());
        user.setRealName(registerRequest.getRealName());
        user.setEmail(registerRequest.getEmail());
        user.setPhone(registerRequest.getPhone());

        userService.createUser(user);
        return ResponseEntity.ok("User registered successfully!");
    }

    @PutMapping("/update")
    public ResponseEntity<?> update(@Valid @RequestBody User user) {
        userService.updateUser(user);
        return ResponseEntity.ok("User update successfully!");
    }

    @DeleteMapping("/delete/{id}")
    public ResponseEntity<?> delete(@PathVariable Long id) {
        userService.deleteUser(id);
        return ResponseEntity.ok("User delete successfully!");
    }

    @GetMapping("/recent/{limit}")
    public ResponseEntity<?> recent(@PathVariable int limit) {
        List<String> latestEvents = auditEventProducer.getLatestEvents(limit);
        return ResponseEntity.ok(latestEvents);
    }

    @Data
    public static class LoginRequest {
        @NotBlank
        private String username;
        @NotBlank
        private String password;
    }

    @Data
    public static class RegisterRequest {
        @NotBlank
        private String username;
        @NotBlank
        private String password;
        private String realName;
        private String email;
        private String phone;
    }
}